package com.probiz.estore.system.service.impl;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;

import com.probiz.estore.Constants;
import com.probiz.estore.common.model.system.AppMenu;
import com.probiz.estore.core.search.SearchCriteria;
import com.probiz.estore.core.service.impl.GenericManagerImpl;
import com.probiz.estore.core.util.I18nUtil;
import com.probiz.estore.system.dao.AppMenuDao;
import com.probiz.estore.system.dao.AppRoleDao;
import com.probiz.estore.system.service.AppMenuManager;


/**
 * Manager implementation for AppMenu, responsible for business processing, and communicate between web and persistence layer.
 */
public class AppMenuManagerImpl extends GenericManagerImpl<AppMenu> implements AppMenuManager {

	private AppMenuDao appMenuDao = null;
	
	private AppRoleDao appRoleDao = null;

	/**
	 * @param appMenuDao
	 *            the appMenuDao to set
	 */
	public void setAppMenuDao(AppMenuDao appMenuDao) {
		this.appMenuDao = appMenuDao;
	}
	public void setAppRoleDao(AppRoleDao appRoleDao) {
		this.appRoleDao = appRoleDao;
	}
	/*
	 * (non-Javadoc)
	 * 
	 * @see com.probiz.estore.core.service.impl.GenericManagerImpl#init()
	 */
	@Override
	protected void initManager() {
		dao = appMenuDao;
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see com.probiz.estore.core.service.impl.GenericManagerImpl#preDelete(java.lang.Object)
	 */
	@Override
	protected void preDelete(AppMenu entity) {

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.probiz.estore.core.service.impl.GenericManagerImpl#preSave(java.lang.Object)
	 */
	@Override
	protected void preSave(AppMenu entity) {

	}
	
	public List<AppMenu> searchByCriteria(SearchCriteria sc,Short belongTo){
		String pid=(String)sc.getParam().get("parentId");
		Short type=null;
		String menuPath=null;
		if(StringUtils.isNotBlank(pid)){
			AppMenu pm = appMenuDao.getById(new Integer(pid));
			if(pm!=null){
				menuPath=pm.getMenuPath_();
				type=pm.getType();
			}else if(pid.equals("-10"))
				type=new Short("0");
			else
				type=new Short("1");
		}
		StringBuffer hqlsb = new StringBuffer("from AppMenu m where m.belongTo=?");
        List<Object> paramList = new ArrayList<Object>();
        paramList.add(belongTo);
        if(type!=null){
        	hqlsb.append(" and m.type = ?");
        	paramList.add(type);
        }
        
        String key =  (String)sc.getParam().get("menuName");
        if(StringUtils.isNotEmpty(key)){
        	hqlsb.append(" and m.menuName like ?");
        	paramList.add("%"+key+"%");
        }
        
        String title =  (String)sc.getParam().get("title");
        if(StringUtils.isNotEmpty(title)){
        	hqlsb.append(" and m.title like ?");
        	paramList.add("%"+title+"%");
        }
        
        if(StringUtils.isNotEmpty(menuPath)){
        	hqlsb.append(" and m.menuPath like ?");
        	paramList.add(menuPath+"%");
        }
        hqlsb.append(" order by menuPath desc,sortOrder asc");
		sc.setHql(hqlsb.toString());
		sc.removeParamValues();
        for (Object object : paramList) {
        	sc.addParamValue(object);
        }
        return super.searchByCriteria(sc);
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.system.service.AppMenuManager#findAllMenus(java.lang.Short, java.lang.Short)
	 */
	public List<AppMenu> findAllMenus(Short belongTo,Short type){
		return appMenuDao.findByHql("from AppMenu am where am.belongTo=? and am.type=? order by am.menuPath,am.sortOrder asc",belongTo,type);
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.system.service.AppMenuManager#findTopMenus(java.lang.Short, java.lang.Short)
	 */
	public List<AppMenu> findTopMenus(Short belongTo,Short type){
		return appMenuDao.findByHql("from AppMenu am where am.parent is null and am.belongTo=? and am.type=? order by am.sortOrder asc", belongTo,type);
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.system.service.AppMenuManager#findChildrenByMenuId(java.lang.Integer)
	 */
	public List<AppMenu> findChildrenByMenuId(Integer parentId){
		return appMenuDao.findByHql("from AppMenu am where am.parent.menuId = ? order by am.sortOrder asc",parentId);
	}
	
	/**
	 * 是否已存在相同的匹配串
	 * @param patternString
	 * @param excludeMenuId
	 * @return
	 */
	public boolean isPatternExist(String menuName, Integer excludeMenuId){
		return appMenuDao.isPatternExist(menuName, excludeMenuId);
	}
	
	public void configToDb(AppMenu menu){
		if(menu.getParent()==null||menu.getParent().getMenuId().intValue()<=0){
			menu.setParent(null);
			menu.setMenuPath(null);
		}else{
			menu.setMenuPath((menu.getParent().getMenuPath()==null?"":menu.getParent().getMenuPath())+menu.getParent().getMenuId()+".");
		}
		if(menu.getBelongTo()==0){
			menu.getAppRoles().add(appRoleDao.getByRoleName(Constants.DEFAULT_ADMIN_ROLE_NAME));
			appRoleDao.getByRoleName(Constants.DEFAULT_ADMIN_ROLE_NAME).getAppMenus().add(menu);
		}
		dao.save(menu);
	}
	
	public void saveFully(boolean isNew,AppMenu menu){

		if(menu.getParent()==null||menu.getParent().getMenuId().intValue()<=0){
			menu.setParent(null);
			menu.setMenuPath(null);
		}else{
			menu.setParent(dao.loadById(menu.getParent().getMenuId()));
			menu.setMenuPath((menu.getParent().getMenuPath()==null?"":menu.getParent().getMenuPath())+menu.getParent().getMenuId()+".");
		}
		//新后台权限缺省授权给超级管理员
		if(isNew && Constants.SECURITY_BELONGTO_ADMIN.equals(menu.getBelongTo()) && StringUtils.isNotBlank(menu.getUrl())){
			appRoleDao.getByRoleName(Constants.DEFAULT_ADMIN_ROLE_NAME).getAppMenus().add(menu);
			menu.getAppRoles().add(appRoleDao.getByRoleName(Constants.DEFAULT_ADMIN_ROLE_NAME));
		}
		dao.save(menu);
	}
	
	public Map<String,Object> deleteFully(Integer appMenuId) {
		Map<String, Object> returnMsgs = new HashMap<String, Object>();
		AppMenu entity = dao.getById(appMenuId);
		//只要不被超级管理员角色所拥有都不能删除
		appRoleDao.getByRoleName(Constants.DEFAULT_ADMIN_ROLE_NAME).getAppMenus().remove(entity);
		entity.getAppRoles().clear();
		Integer parentId = entity.getParent()==null?0:entity.getParent().getMenuId();
		String title = entity.getTitle();
		if(parentId.intValue()==0){
			if(entity.getBelongTo().shortValue()==1){
				parentId=-11;
			}else{
				parentId=-10;
			}
		}
		dao.delete(entity);
		
		
		returnMsgs.put("result", 1);
		returnMsgs.put("message", I18nUtil.getInstance().getMessage("appMenu.del.success",new Object[]{title}));
		returnMsgs.put("parentId", parentId);
		return returnMsgs;
	}


	
	public AppMenu getAppMenuByMenuName(String menuName){
		return dao.getUniqueByProperty("menuName", menuName);
	}
	
	public void updateMenusSortOrder(Integer[] menuIds)  {
		for (int i = 0; i < menuIds.length; i++) {
			Integer menuId = menuIds[i];
			AppMenu menu=getById(menuId);
			if(menu==null)continue;
			try {
				BeanUtils.setProperty(menu,"sortOrder",(i+1));
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
			save(menu);
		}
	}

}
